package com.common.ui.controls;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;

public abstract class ModalProgressDialog 
{
	
	private static final int NORMAL_HEIGHT = 200;
	private static final int EXPANDED_HEIGHT = 300;
	
	private JDialog dialog;
	private JPanel contentPanel;
	private JTextArea detailArea;
	private JScrollPane textScroll;
	private ModalProcess process;
	private boolean firstUpdate;
	
	public ModalProgressDialog(ModalProcess process,Frame owner)
	{
		dialog = new JDialog(owner,process.getProcessName());
		dialog.setSize(500, EXPANDED_HEIGHT);
		dialog.setTitle(process.getProcessName());
		dialog.setModal(true);
		dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
		this.process = process;
		buildContent();
		dialog.setContentPane(contentPanel);
		firstUpdate = true;
	}
	
	protected void buildContent()
	{
		contentPanel = new JPanel(new BorderLayout());
		contentPanel.add(getStatusComponent(),BorderLayout.CENTER);
		contentPanel.add(getButtonPanel(),BorderLayout.PAGE_END);
	}
	
	public abstract JComponent getStatusComponent();
	
	protected JPanel getButtonPanel()
	{
		JPanel panel = new JPanel(new GridBagLayout());
		JPanel buttonPanel = new JPanel();
		buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT,10,10));
		JButton button;		
		buttonPanel.add(button = new JButton("Cancel"));
		button.addActionListener(new ActionListener() 
		{
			public void actionPerformed(ActionEvent e) 
			{
				process.cancel();
				((JButton) e.getSource()).setText("Cancelling");
				((JButton) e.getSource()).setEnabled(!process.isCancelled());
			}
		});
		buttonPanel.add(button = new JButton("Details <<"));
		button.addActionListener(new ActionListener() 
		{
			public void actionPerformed(ActionEvent e) 
			{
				textScroll.setVisible(!textScroll.isVisible());
				((JButton)e.getSource()).setText(textScroll.isVisible() ? "Details <<" : "Details >>");
				Dimension dim = dialog.getSize();
				dim.height = textScroll.isVisible() ? EXPANDED_HEIGHT : NORMAL_HEIGHT;
				dialog.setSize(dim);
			}
		});
		GridBagConstraints gc = new GridBagConstraints();
		gc.weightx = 100; 
		gc.fill = GridBagConstraints.HORIZONTAL;
		gc.gridwidth = GridBagConstraints.REMAINDER;
		gc.anchor = GridBagConstraints.EAST;
		panel.add(buttonPanel,gc);
		panel.add(new JSeparator(),gc);
		gc.weighty = 100;
		gc.fill = GridBagConstraints.BOTH;
		gc.insets = new Insets(15,3,5,3);
		detailArea = new JTextArea(8,5);
		detailArea.setEditable(false);
		textScroll = new JScrollPane(detailArea);
		panel.add(textScroll,gc);
		return panel;
	}
	
	public void updateStatus(Object status,boolean newLine)
	{
		if(firstUpdate)
		{
			firstUpdate = false;
			newLine = false;
		}
		detailArea.setText(detailArea.getText() + (newLine ? "\n" : "") + status.toString());
	}
	
	public abstract void updateInfo(Object info);
	
	public void showProgress()
	{
		SwingUtilities.invokeLater(new Runnable() 
		{
			public void run()
			{
				dialog.setVisible(true);
			}
		});
	}
	
	public void dispose()
	{
		dialog.dispose();
	}
}
